/*
    This file is part of Raptor.

    Raptor is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Raptor is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Raptor.  If not, see <http://www.gnu.org/licenses/>.

 */

#ifndef __XMLFILELOADER_H__
#define __XMLFILELOADER_H__

#include <QObject>
#include <QHttp>
#include <QNetworkProxy>
#include <QFile>
#include <QDir>
#include <QUrl>
#include <QTimer>
#include <QDateTime>
#include <QDomDocument>
#include <QPointer>

/*! \class xmlFileLoader

    \brief Downloads files.

    QObject that parses an xml file for loading files from the hoster specified in the xml file.
 */

class xmlFileLoader : public QObject
{
	Q_OBJECT

	public:

		enum E_MODE
		{
			MODE_FREE,
			MODE_PREMIUM,
			MODE_LOGIN,
			MODE_GET_SIZE,
		};

		enum E_ERROR
		{
			ERROR_NO_ERROR,
			ERROR_XML,
			ERROR_HTTP,
			ERROR_FILE,
		};

		enum E_STATE
		{
			STATE_LOAD_XML,
			STATE_ERROR,
			STATE_RUNNING,
			STATE_FINISHED,
			STATE_WAITING,
			STATE_DOWNLOADING,
			STATE_STOPPED,
			STATE_STALLED,
			STATE_HISTORY,
			STATE_DELETE,
		};

		enum E_ACTION_TYPE
		{
			TYPE_NO_FOUND,
			TYPE_OPEN_URL,
			TYPE_METHOD_GET,
			TYPE_METHOD_GET_DOWNLOAD,
			TYPE_METHOD_POST,
			TYPE_METHOD_POST_DOWNLOAD,
			TYPE_REGEXP,
			TYPE_MULTI_REGEXP,
			TYPE_GET_SIZE,
			TYPE_STEP,
			TYPE_DO_STEP,
			TYPE_HALT,
			TYPE_HALT_LOGIN,
			TYPE_HALT_GET_SIZE,
			TYPE_WAIT,
			TYPE_PREPARE_DOWNLOAD,
			TYPE_FINISH_DOWNLOAD,
			TYPE_SELECT_MIRROR,
			TYPE_CHECK_FILE,
			TYPE_CHECK_SIZE,
			TYPE_CHECK_CONTENT,
			TYPE_DUMMY,
			TYPE_DELETE_FILE,
			TYPE_SET_STATE,
			TYPE_BREAK_CHECK,
			TYPE_SET_COOKIE,
			TYPE_SAVE_COOKIE,
			TYPE_LOAD_SETTINGS,
			TYPE_HEADER,
			TYPE_WAIT_HTTP,
			TYPE_MODE,
			TYPE_BOOL_FCT,
			TYPE_SET_ERROR,
			TYPE_EMIT_STATE,
		};

		struct S_WAITFOR
		{
			QDomNode node;
			int it;

			S_WAITFOR(const QDomNode &n, int i)
			{
				node = n;
				it = i;
			}
		};

		xmlFileLoader();
		~xmlFileLoader();

		bool isValidHoster(const QString &host);
		void loadXml(const QString &xmlFile);

		bool setLink(const QUrl &newUrl);
		void setFile(const QString &newFile);
		void setFolder(const QString &newFolder);
		void setDownloadDir(const QString &newFolder);
		void setId(const int &newId);
		void setMode(const E_MODE &newMode);
		void setLogId(const int &newId);

                void setProxy(QNetworkProxy const &proxy);

		void start();
		void stop();
		void login(const QString &user, const QString &pass);
		void getSize();

		int state();
		int error();
		int progress();
		int mode();
		double speed();
		int timeLeft();
		QString link();
		QString errorStr();
		int logId();

		QDateTime downloadStart();
		uint fileSize();
		uint downloaded();

		QPointer<QFile> downloadFile();

	public slots:

	signals:
		void loginFinished(const int id, const bool error);
		void getSizeFinished(const int id, const bool error);
		void downloadFinished(const int &id, const bool &error);
		void statusMsg(const int &id, const QString &msg);
		void changeMode(const int &id, const xmlFileLoader::E_MODE mode);

	private:

		bool verbose;

		QHttp http;
		QByteArray response;
		QString cookie;
		QString page;

		bool reinitLoop;
		bool waitForHttp;
		int waitInsertAt;
		QList<S_WAITFOR> waitHttp;

		int waitingId;

		uint m_fileSize;
		uint m_downloaded;
		int m_progress;

		E_STATE m_state;
		E_ERROR m_error;
		E_MODE m_mode;

		int step;

		//timer
		QTimer waitTimer;
		int m_timeLeft;
		int wait;
		int timerStep;
		///timer

		bool continueCheck;

		QMap<QString, QString> regExpResults;
		QMap<QString, QStringList> regExpListResults;

		QDomDocument domHoster;

		int id;
		int m_logId;
		int maxConnectionsPerDownloads;

		QString m_errorStr;

		QUrl url;
		QString host;

		QPointer<QFile> m_downloadFile;
		//QFile * downloadFile;
		QString file;
		QString folder;
		QDir downloadDir;

		QDateTime m_downloadStart;
		QDateTime downloadEnd;
		uint lastSize;

		double m_speed;
		QList<double> speedList;
		QTimer speedTimer;
		int smooth;
		int speedIntervall;

		bool loadXmlFile(const QString &xmlFile);
		void loadVar();

		void doStep();
		void doAction(const QDomNode &parent, const int startI=0);

		int parseType(const QString &type);
		int parseState(const QString &state);

		void switchAction(const QDomNode &action);
		bool switchResult(const QDomNode &result);

		void setSpeed(const double &newSpeed);

		QString getVar(const QString &var);
		QStringList getListVar(const QString &var);

		void addVar(const QString &key, const QString &value);
		bool checkAttributes(const QDomNode &node, const QStringList &attributes);

	protected:


	private slots:

		//void slot_http_done(bool httpError);
		void slot_http_requestFinished(int requestId, bool httpError);
		void slot_http_readyRead(const QHttpResponseHeader & resp);
		void slot_http_dataReadProgress(int done, int total);
		void slot_http_sslErrors(const QList<QSslError> & errors);

		void slot_waitTimer_timeout();
		void slot_speedTimer_timeout();
};
#endif
